﻿using System;
using System.Collections.Generic;
using System.Text;
using AdaptiveAgents.Loggers;

namespace AdaptiveAgents.Agents.Choosers
{
    /// <summary>
    /// Chooses the next player in greedy form
    /// </summary>
    class GreedyNextPlayerChooser : NextPlayerChooser
    {
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="agent">the agent which the chooser is being assigned to</param>
        public GreedyNextPlayerChooser(Agent agent)
            : base(agent)
        {
            agent.NextPlayerChooser = this;
        }

        /// <summary>
        /// Choose the next player according to the mean of performence
        /// </summary>
        /// <param name="maxToConsider">Limitation on index of agent</param>
        /// <returns>index of next player</returns>
        public override int choose(int maxToConsider)
        {
            //Perform a random choice until reaching the change strategy point
            if (_me.ObservationsSet.observations.Count < _me.ChangeStrategyPoint)
            {
                //choose randomly the next player
                return Generator.getNextInt(_me.Environment.agents.Count); //3
            }

            double maxComp = -Double.MaxValue;
            Agent maxAgent = null;
            foreach (Agent agent in _me.Environment.agents)
            {
                if (agent.ID >= maxToConsider) break;
                double comp;
                if (agent.ID == _me.ID) // AGENTS know own competence
                    comp = _me.Competence.Mean;
                else
                    comp = _me.getTeammateModel(agent.ID).EstimateCompetence();
                AdaptiveAgents.logger.WriteLine(MessageType.OtherAgentCompetence, _me.ID, agent.ID, comp);

                int numTies = 1;
                if (comp > maxComp)
                {
                    maxComp = comp;
                    maxAgent = agent;
                    numTies = 1;
                }
                else if (Math.Abs(comp - maxComp) < .000001)
                {
                    numTies++;
                    AdaptiveAgents.logger.WriteLine(MessageType.AgentTied, numTies);

                    if (Generator.getNextDouble() < 1.0 / numTies)
                    {
                        maxAgent = agent;
                    }
                }
            }
            return maxAgent.ID;
        }
    }
}
